package gateway.config.security.auth;

import cn.hutool.core.collection.CollectionUtil;
import common.config.http.HttpStatusEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 顺序：3
 * url权限认证
 *
 * @author 米泽鹏
 * @since 2021-08-06 9:53 上午
 */
@Component
@Slf4j
public class CustomAccessDecisionManager implements AccessDecisionManager {

	@Override
	public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {
		// 有当前url的权限的角色
		Set<String> validRoleSet = configAttributes.stream().map(ConfigAttribute::getAttribute).collect(Collectors.toSet());
		if (validRoleSet.size() == 1 && HttpStatusEnum.FORBIDDEN.name().equals(validRoleSet.stream().findFirst().get())) {
			throw new AccessDeniedException(HttpStatusEnum.FORBIDDEN.getMessage());
		}
		// 当前用户所具有的角色
		Set<String> roleCodeSet = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet());
		// 只要包含其中一个角色即可访问
		if (CollectionUtil.containsAny(roleCodeSet, validRoleSet)) {
			return;
		}
		log.error("禁止访问");
		throw new AccessDeniedException(HttpStatusEnum.FORBIDDEN.getMessage());
	}

	@Override
	public boolean supports(ConfigAttribute attribute) {
		return true;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

}
